// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "DBManager/Repository/HDF5/Input/Constraint/IndexMappingRepository.h"

#include <algorithm>
#include <cstddef>
#include <set>
#include <vector>

#include "DataStructure/Common/Id.h"
#include "DataStructure/Common/Integer.h"
#include "DataStructure/Common/Status.h"
#include "DataStructure/Input/Constraint/ConstraintType.h"

#include "DBManager/Database/HDF5Database.h"
#include "DBManager/IRepository/Input/Constraint/IIndexMappingRepository.h"
#include "DBManager/Repository/HDF5/Base/HDF5RepositoryMacro.h"
#include "DBManager/Repository/HDF5/Base/SingleRepositoryBase.h"

HDF5_REG_NO_SORT_REPOSITORY (IndexMappingRepository)

using namespace SG::DBManager::HDF5;

using namespace SG::DBManager;
using namespace SG::DataStructure::FEM;
IndexMappingRepository::IndexMappingRepository (HDF5Database& database) : RepositoryBase (database)
{}

void IndexMappingRepository::InitialDatasetInfo ()
{
    RegisterTableInfo<SG::DataStructure::FEM::IndexMappingData> ("/OWN/INPUT/CONSTRAINT/INDEX_MAPPING", MainDataset);
}

/// @brief 使用vector批量添加数据
/// @param entitys
SG::DataStructure::Common::Status IndexMappingRepository::Add (std::vector<SG::DataStructure::FEM::IndexMappingData>& entitys)
{
    // 创建数据集
    if (!this->GetMainDatasetInfo ().IsCreate ())
    {
        CreateDatasetInFile ();
    }

    // 获取数据集的路径和数据集对象
    HighFive::DataSet dataset = this->GetDataset (MainDataset);

    // 获取数据集的大小和起始位置
    const std::size_t start = Size ();
    const std::size_t count = entitys.size ();

    // 调整数据集的大小
    dataset.resize ({ start + count });

    // 写出数据
    dataset.select ({ start }, { count }).write (entitys);

    return SG::DataStructure::Common::Status::STATUS_Success;
}

/// @brief 获取所有ID
/// @return 局部到全局
SG::DataStructure::FEM::IndexMapping IndexMappingRepository::GetIndexMapping ()
{
    SG::DataStructure::FEM::IndexMapping part2GlobalMap;

    if (this->GetMainDatasetInfo ().IsCreate ())
    {
        std::vector<SG::DataStructure::FEM::IndexMappingData> Alldata;
        GetDataset (MainDataset).read (Alldata);
        part2GlobalMap.reserve (Alldata.size ());
        for (const SG::DataStructure::FEM::IndexMappingData& item : Alldata)
        {
            part2GlobalMap.emplace (
                item.GIndex,
                std::vector<SG::DataStructure::Common::I64>{
                    item.DOFIndex[0], item.DOFIndex[1], item.DOFIndex[2], item.DOFIndex[3], item.DOFIndex[4], item.DOFIndex[5] });
        }
    }

    return part2GlobalMap;
}

/// @brief 获取总数
/// @return
std::size_t IndexMappingRepository::Size ()
{
    return GetDataset (MainDataset).getElementCount ();
}